cbuffer cbPerObject
{
	float4x4 WorldViewProjection;	
	float4x4 WorldView;	
	float4x4 View;	
	float4x4 InverseProjection;
	float4x4 ViewToLightProjection;
	float4x4 ViewToLightView;
}

cbuffer cbGlobal
{
	int2 screenSize;
	float zFar;
//	float4 light;
}

SamplerState DepthSampler
{
	Filter = MIN_MAG_POINT_MIP_LINEAR;
    AddressU = Clamp;
    AddressV = Clamp;
};

Texture2D depthTexture;

struct App2VS
{
	float3 pos : POSITION;
	float3 col : COLOR;
	float3 normal : NORMAL;
};
struct VS2PS
{
	float4 pos : SV_Position;
	float3 viewRay : TEXCOORD0;
};
struct PS2GPU
{
	float4 value : SV_Target0;
};

void vs(App2VS IN, out VS2PS OUT)
{
	OUT.pos = float4(IN.pos, 1); //pass through for quad/etc
	float4 viewPos = mul(float4(IN.pos.xy, 1, 1), InverseProjection);
	OUT.viewRay = viewPos.xyz / viewPos.w;
}
void ps(VS2PS IN, out PS2GPU OUT)
{
    float K0 = .5f;
    float C3 = 6.f;
    float C4 = 6.f;
    
	float2 uv = IN.pos / screenSize;
	float depth = depthTexture.Sample(DepthSampler, uv).r;

    float3 centerDir = float3(0, 0, 1);
    float3 pixDir = normalize(IN.viewRay);

    float2 pixOffset = IN.pos.xy - screenSize / 2;
    pixOffset = pixOffset / screenSize;

    float dHeading = dot(centerDir, pixDir);

    float angAcc =        
        K0 * dHeading
        * exp(-C3 * abs(dHeading))
        * exp(-C4 * depth);

    if(depth == -1)
        OUT.value = 0;
    else        
        OUT.value = float4(angAcc * -1 * pixOffset, 0, 1);
    return;
}
technique10 Render
{
	pass P0
	{
		SetGeometryShader( 0 );
		SetVertexShader( CompileShader( vs_4_0, vs() ) );
		SetPixelShader( CompileShader( ps_4_0, ps() ) );
	}
}